
use tokio::sync::{mpsc, oneshot};

#[tokio::main]
async fn main() {


    let mut db = vec![1,2,3];
    // 普通类型没有返回值
    let (tx, mut rx) = mpsc::channel::<i32>(20);
    // 使用oneshot可以携带一个返回值
    let (tx, mut rx) = mpsc::channel::<(i32, oneshot::Sender<bool>)>(20);

    // tx本质上是arc
    let tx1 = tx.clone();
    let tx2 = tx.clone();

    // 代码遇到tokio::spawn会自动创建一个task并执行，只是不阻塞当前线程
    let process_task = tokio::spawn(async move {
        while let Some((value, sender)) = rx.recv().await {
            println!("got = {}", value);
            db[1] = value;
            println!("db = {:?}", db);
            sender.send(true).unwrap();
        }
    });

    let task1 = tokio::task::spawn(async move {
        println!("task1 run");
        let (oneshot_tx,oneshot_rx ) = oneshot::channel();
        if let Err(_) = tx1.send((1, oneshot_tx)).await {
            return;
        }
        // 等待oneshot_rx返回值
        if let Ok(r) = oneshot_rx.await {
            if r {
                println!("task1 ok");
            } else {
                println!("task1 error");
            }
        }

    });

    let task2 = tokio::task::spawn(async move {
        println!("task2 run");
        let (one_tx, one_rx) = oneshot::channel();
        if let Err(_) = tx2.send((2, one_tx)).await {
            return;
        }
        if let Ok(r) = one_rx.await {
            if r {
                println!("task2 ok");
            } else {
                println!("task2 error");
            }
        }

    });
    process_task.await.unwrap();

}